package org.jground.rx.ui.zk.viewControl;

import java.util.Date;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jground.rx.RX;
import org.jground.rx.RXType;
import org.jground.rx.RXView;
import org.jground.rx.ui.IUIAttributeView;
import org.jground.rx.ui.zk.UIFrame;
import org.jground.util.ArrayUtils;
import org.jground.util.DateUtils;
import org.jground.util.StringUtils;
import org.jground.zk.zulX.HboxX;
import org.zkoss.zk.ui.Component;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.Decimalbox;
import org.zkoss.zul.Intbox;
import org.zkoss.zul.Label;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.Timebox;
import org.zkoss.zul.impl.InputElement;

public class UIAttributeControlString extends UIAttributeControlBase {

    private static Log logger = LogFactory.getLog(_DATETIME.class);

    protected InputElement field;
    protected Label prefix;
    protected Label postfix;
    protected boolean mandatory;
    protected int maxChars;
    protected int maxCols;
    protected int rows;

    public UIAttributeControlString() {
        super();
    }

    private UIAttributeControlString(UIFrame uiFrame, RXView rxControl) {
        super(uiFrame, rxControl);
        RXType txType = rxControl.getRXAttribute().getRXType().getBaseType();
        //
        mandatory = rxControl.getRXAttribute().isMandatory();
        //
        maxChars = txType.getMaxChars();
        maxCols = rxControl.getPropertyWithDefault(RX.AttName.maxcols, 34);
        rows = rxControl.getPropertyWithDefault(RX.AttName.rows, 8);
        if (maxCols > maxChars) {
            maxCols = maxChars + 2;
        }
    }

    public IUIAttributeView<Component,UIFrame> createNew(UIFrame uiFrame, RXView moControl) {
        RXType moType = moControl.getRXAttribute().getRXType().getBaseType();
        String typeId = moType.getTypeId();
        if (RXType.STRING.equals(typeId)) {
            return new _STRING(uiFrame, moControl);
        }
        if (RXType.TEXT.equals(typeId)) {
            return new _TEXT(uiFrame, moControl);
        }
        if (RXType.INTEGER.equals(typeId)) {
            return new _INTEGER(uiFrame, moControl);
        }
        if (RXType.FLOAT.equals(typeId)) {
            return new _FLOAT(uiFrame, moControl);
        }
        if (RXType.PERCENTAGE.equals(typeId)) {
            return new _PERCENTAGE(uiFrame, moControl);
        }
        if (RXType.DATE.equals(typeId)) {
            return new _DATE(uiFrame, moControl);
        }
        if (RXType.TIME.equals(typeId)) {
            return new _TIME(uiFrame, moControl);
        }
        if (RXType.DATETIME.equals(typeId)) {
            return new _DATETIME(uiFrame, moControl);
        }
        return new UIAttributeControlString(uiFrame, moControl);
    }

    @Override
    public void set(String... values) {
        clear();
        try {
            if (ArrayUtils.isNotEmpty(values) && StringUtils.isNotBlank(values[0])) {
                String value = values[0];
                field.setText(value);
            }
        } catch (Exception e) {
            logger.warn(e, e);
        }

    }

    @Override
    public String[] get() {
        try {
            String s = field.getText() == null ? "" : field.getText();
            return ArrayUtils.toArray(s);
        } catch (Exception e) {}
        return StringUtils.EMPTY_STRING_ARRAY;
    }

    @Override
    public void clear() {
        field.setText("");
    }

    /*
     * 
     * CLASSES FOR ALL TYPES
     */

    private class _STRING extends UIAttributeControlString {
        private Textbox textbox;

        _STRING(UIFrame uiFrame, RXView moControl) {
            super(uiFrame, moControl);
            textbox = new Textbox();
            // if (mandatory) {
            // textbox.setConstraint("no empty");
            // }
            textbox.setMaxlength(maxChars);
            int px = maxCols * 10;
            textbox.setWidth(px + "px");
            if (RX.AttValue.password.equals(moControl.getProperty(RX.AttName.display))) {
                textbox.setType("password");
            }
            super.field = textbox;
            add(field);
        }
    }

    private class _TEXT extends UIAttributeControlString {
        private Textbox textbox;

        _TEXT(UIFrame uiFrame, RXView moControl) {
            super(uiFrame, moControl);
            textbox = new Textbox();
            // if (mandatory) {
            // textbox.setConstraint("no empty");
            // }
            textbox.setRows(rows);
            textbox.setMaxlength(maxChars);
            //int px = maxCols * 10;
            // textbox.setWidth(px + "px");
            textbox.setWidth("99%");

            super.field = textbox;
            add(field);
        }
    }

    private class _INTEGER extends UIAttributeControlString {
        private Intbox intbox;

        _INTEGER(UIFrame uiFrame, RXView moControl) {
            super(uiFrame, moControl);
            intbox = new Intbox();
            // if (mandatory) {
            // intbox.setConstraint("no empty");
            // }
            intbox.setMaxlength(maxChars);
            int px = maxCols * 10;
            intbox.setWidth(px + "px");

            super.field = intbox;
            add(field);
        }
    }

    private class _FLOAT extends UIAttributeControlString {
        // private Decimalbox decbox;
        private Textbox decbox;

        _FLOAT(UIFrame uiFrame, RXView moControl) {
            super(uiFrame, moControl);
            decbox = new Textbox();
            // if (mandatory) {
            // decbox.setConstraint("no empty");
            // }
            decbox.setMaxlength(maxChars);
            int px = maxCols * 10;
            decbox.setWidth(px + "px");
            super.field = decbox;

            add(field);
        }
    }

    private class _PERCENTAGE extends UIAttributeControlString {
        private Decimalbox decbox;

        _PERCENTAGE(UIFrame uiFrame, RXView moControl) {
            super(uiFrame, moControl);
            decbox = new Decimalbox();
            // if (mandatory) {
            // decbox.setConstraint("no empty");
            // }
            decbox.setMaxlength(maxChars);
            int px = maxCols * 10;
            decbox.setWidth(px + "px");
            postfix = new Label("%");

            super.field = decbox;
            add(new HboxX(field, postfix));
        }
    }

    private class _DATE extends UIAttributeControlString {
        private Datebox datebox;

        _DATE(UIFrame uiFrame, RXView moControl) {
            super(uiFrame, moControl);
            datebox = new Datebox();
            datebox.setFormat(DateUtils.ISO_DATE_PATTERN_yyyy_MM_dd);
            // if (mandatory) {
            // datebox.setConstraint("no empty");
            // }
            add(datebox);
        }

        @Override
        public void set(String... values) {
            try {
                if (ArrayUtils.isNotEmpty(values) && StringUtils.isNotBlank(values[0])) {
                    String value = values[0];
                    Date date = DateUtils.parseDate(value);
                    datebox.setValue(date);
                    return;
                }
            } catch (Exception e) {
                logger.warn("in _DATE " + e, e);
            }
            try {
                datebox.setText("");
            } catch (Exception e) {}
        }

        @Override
        public String[] get() {
            try {
                Date value = datebox.getValue();
                if (value == null) {
                    return StringUtils.EMPTY_STRING_ARRAY;
                }
                String d = DateUtils.formatToDate(value);
                return ArrayUtils.toArray(d);
            } catch (Exception e) {
                logger.warn("in _DATE " + e, e);
            }
            return StringUtils.EMPTY_STRING_ARRAY;
        }

        @Override
        public void clear() {
            set("");
        }
    }

    private class _TIME extends UIAttributeControlString {
        private Timebox timebox;

        _TIME(UIFrame uiFrame, RXView moControl) {
            super(uiFrame, moControl);
            timebox = new Timebox();
            // timebox.setFormat(DateUtils.ISO_DATE_PATTERN_HH_mm);
            // if (mandatory) {
            // timebox.setConstraint("no empty");
            // }
            add(timebox);
        }

        @Override
        public void set(String... values) {
            try {
                if (ArrayUtils.isNotEmpty(values) && StringUtils.isNotBlank(values[0])) {
                    String value = values[0];
                    Date date = DateUtils.parseTime(value);
                    timebox.setValue(date);
                    return;
                }
            } catch (Exception e) {
                logger.warn("in _TIME " + e, e);
            }
            try {
                timebox.setText("");
            } catch (Exception e) {}
        }

        @Override
        public String[] get() {
            try {
                Date value = timebox.getValue();
                if (value == null) {
                    return StringUtils.EMPTY_STRING_ARRAY;
                }
                String t = DateUtils.formatToTime(value);
                return ArrayUtils.toArray(t);
            } catch (Exception e) {
                logger.warn("in _TIME " + e, e);
            }
            return StringUtils.EMPTY_STRING_ARRAY;
        }

        @Override
        public void clear() {
            set("");
        }

    }

    private class _DATETIME extends UIAttributeControlString {

        private Datebox datebox;
        private Timebox timebox;

        _DATETIME(UIFrame uiFrame, RXView moControl) {
            super(uiFrame, moControl);
            datebox = new Datebox();
            timebox = new Timebox();
            datebox.setFormat(DateUtils.ISO_DATE_PATTERN_yyyy_MM_dd);
            // timebox.setFormat(DateUtils.ISO_DATE_PATTERN_HH_mm);
            // if (mandatory) {
            // datebox.setConstraint("no empty");
            // timebox.setConstraint("no empty");
            // }
            add(new HboxX(datebox, timebox));
        }

        @Override
        public void set(String... values) {
            try {
                if (ArrayUtils.isNotEmpty(values) && StringUtils.isNotBlank(values[0])) {
                    String value = values[0];
                    Date date = DateUtils.parseDateTime(value);
                    datebox.setValue(date);
                    timebox.setValue(date);
                    return;
                }
            } catch (Exception e) {
                logger.warn("in _DATETIME " + e, e);
            }
            try {
                timebox.setText("");
            } catch (Exception e) {}
            try {
                datebox.setText("");
            } catch (Exception e) {}
        }

        @Override
        public String[] get() {
            try {
                Date dateValue = datebox.getValue();
                if (dateValue == null) {
                    return StringUtils.EMPTY_STRING_ARRAY;
                }

                Date timeValue = timebox.getValue();
                if (timeValue == null) {
                    return ArrayUtils.toArray(DateUtils.formatToDate(dateValue));
                }
                String d = DateUtils.formatToDate(dateValue);
                String t = DateUtils.formatToTime(timeValue);
                return ArrayUtils.toArray(d + " " + t);
            } catch (Exception e) {
                logger.warn("in _DATETIME " + e, e);
            }
            return StringUtils.EMPTY_STRING_ARRAY;
        }

        @Override
        public void clear() {
            set("");
        }

    }
}
